package LAAMI;

import java.util.*;
import repast.simphony.engine.environment.RunEnvironment;
import repast.simphony.engine.schedule.ScheduledMethod;
import repast.simphony.parameter.Parameter;
import repast.simphony.random.RandomHelper;
import umontreal.iro.lecuyer.randvar.NormalGen;
import umontreal.iro.lecuyer.rng.MRG32k3a;
import umontreal.iro.lecuyer.rng.RandMrg;
import umontreal.iro.lecuyer.rng.RandRijndael;
import umontreal.iro.lecuyer.rng.RandomStream;
import umontreal.iro.lecuyer.rng.RandomStreamBase;
import umontreal.iro.lecuyer.stochprocess.BrownianMotion;
import umontreal.iro.lecuyer.stochprocess.GeometricBrownianMotion;

public class StockMarket {

	private double price;
	private double volatility;
	private double drift;
	public ArrayList priceList;
	private double strikePrice;
	NormalGen gen;
	RandomStream stream;
	private BrownianMotion brownian;

	//
	public StockMarket(double initialPrice, double volatility, double drift) {
		setPrice(initialPrice);
		priceList = new ArrayList();
		priceList.add(price);

		setDrift(drift);
		setVolatility(volatility);
		setStrikePrice(0);
		
		//We use SSJ library functions to produce the Brownian motion 
		stream = new MRG32k3a();
		gen = new NormalGen(stream, drift, volatility);
		brownian = new BrownianMotion(initialPrice, drift, volatility, stream);
	}

	// In every step it's the first method to be calculated.
	// We generate a random walk following a Brownian movement and we sample it
	// every 100 steps to produce the stock market prices.
	// We create 5 different strike prices close to the stock price at the 51th
	// day.
	@ScheduledMethod(start = 1, interval = 1, priority = 1)
	public void step() {
		double p;
		brownian.generatePath();
		while ((p = brownian.nextObservation(price, 1)) < 0) {
		}
		setPrice(p);
		priceList.add(price);
		int day = (int) RunEnvironment.getInstance().getCurrentSchedule()
				.getTickCount();
		if (day == 51) {
				double r=RandomHelper.nextDoubleFromTo(0.5, 1.5);
				setStrikePrice(price * r);
		}
	}

	

	/* -------------setters/getters-------------------- */
	public double getPrice() {
		return price;
	}

	public double getDrift() {
		return drift;
	}

	public void setDrift(double d) {
		drift = d;
	}

	public void setPrice(double p) {
		price = p;
	}

	public double getVolatility() {
		return volatility;
	}

	public void setVolatility(double v) {
		volatility = v;
	}

	public double getStrikePrice() {
		return strikePrice;
	}

	public void setStrikePrice(double s) {
		strikePrice = s;
	}
	
}
